<?php
/**
 * 
 * @author gp·s
 *
 */
class DB
{
    private $dbh;           // 数据库句柄
    private $statement;     // 流对象
    private $result;        // 结果集
    
    private $error_message; // 错误信息
    
    /**
     * 
     * @param string $dsn
     * @param string $username
     * @param string $password
     * @param array $driver_options
     */
    public function __construct($dsn, $username = '', $password = '', $driver_options = array())
    {
        try 
        {
            $this->dbh = new PDO($dsn, $username, $password);
        } 
        catch (PDOException $e) 
        {
            
            echo $e->getMessage();	                    // 取得文本化的错误信息
            // var_dump($e->getCode());	                // 取得 SQLSTATE 错误代号
            // var_dump($e->getFile());	                // 取得发生异常的文件名
            // var_dump($e->getLine());	                // 取得 PHP 程序产生异常的代码所在行号
            // var_dump($e->getTrace());	            // backtrace();数组
            // var_dump($e->getTraceAsString());        // 取得已格成化成字符串的 getTrace() 信息
            die();
        }  
    }
    
    /**
     * 
     * @param string $sql
     * @return number
     */
    public function execSQL($sql)
    {
        return $this->dbh->exec($sql);
    }
    
    /**
     * 默认返回数组， $type=true返回对象
     * 从结果集中获取下一行
     * 前面需要执行了单挑结果集才可使用
     * 
     * @param bool $type
     * @return multitype:   
     */
    public function getNextLineData()
    {
        $this->result = $this->statement->fetch();
        
        return $this->result;
    }
    
    
    /**
     * 不绑定参数："insert into `message`(`user_name`, `time`, `notes`) values('iiiiiiiiiii', '2016-1-1', ':notes')
     * 绑定参数   ：
     * 
     * @param string $sql
     * @param array $param
     * @param bool $type
     */
    public function noneQuery($sql, $param = array())
    {
        // 绑定参数 并执行   返回的结果集在  $this->statement
        return $this->paramBindExec($sql, $param);
    }
    
    /**
     * 
     * @param string $sql
     * @param string $param
     * @param bool $results
     * @return mixed
     */
    public function query($sql, $param = array(), $results = false)
    {
        // 绑定参数 并执行   返回的结果集在  $this->statement
        $this->paramBindExec($sql, $param);
        $this->getTypeData($results);
        
        return $this->result;
    }
    
    /**
     * 第二个参数格式必须与第一个参数对应
     * $db->paramBindExec("select user_name, notes from message where user_name=:user_name", array(':user_name'=>'guest'), false);
     * 
     * @param string $sql
     * @param array $param
     * @param string $type
     */
    private function paramBindExec($sql, $param)
    {
        try
        {
            $this->statement = $this->dbh->prepare($sql);

            // 绑定参数
            if (!empty($param))
            {
                foreach ($param as $key=>$value)
                {
                    $this->statement->bindParam($key, $param[$key]);
                } 
 
            }
            
            // 执行预处理语句      成功返回true   失败返回false
            return $this->statement->execute();
        }
        catch (PDOException $e)
        {
            echo $e->getMessage();
        }
    }
    
    /**
     * 根据参数返回数组或者对象
     *
     * @param bool $type
     */
    private function getTypeData($results)
    {
        if ($results)
        {
            $this->result = $this->statement->fetchAll();
        }
        else
        {
            $this->result = $this->statement->fetch();
        }
    }
       
    public function __destruct()
    {
        $this->dbh = null;
    }
}